
#define FID_MANAGE_IO

//#include "manage_io.h"
#include "main.h"

extern 	uint16_t  u16_sm_step = 0u;

void mio_init(void)
{
	di_do_port_init();//DI/DO端口初始化
	
	mio_init_val();//DI/DO变量初始化
	
	DI_DIAG_SET_PULSE();//T1/T2控制口置高电平
}

static void mio_init_val(void)//初始化变量值
{
	uint16_t	u16_idx	= 0u;
	for(u16_idx = 0u; u16_idx < MAX_IO_NUM_DI; u16_idx ++)
	{
		g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm = 0u;
		g_st_ram2.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm = 0u;
	}
	
	g_st_ram1.run_auxiliary_data.u16_di_val	= 0u;
	g_st_ram1.run_auxiliary_data.u16_do_val	= 0u;
	g_st_ram1.run_auxiliary_data.u16_do_pul	= 0x5555u;
	g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw	= 0u;
	g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		= 0u;
	g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	= comm_tim_get_currt_cnt();
	
  //备份
	g_st_ram2.run_auxiliary_data.u16_di_val	= g_st_ram1.run_auxiliary_data.u16_di_val;
	g_st_ram2.run_auxiliary_data.u16_do_val	= g_st_ram1.run_auxiliary_data.u16_do_val;
	g_st_ram2.run_auxiliary_data.u16_do_pul	= g_st_ram1.run_auxiliary_data.u16_do_pul;
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw	= g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw;
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		= g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt;
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	= g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old;
	
}

void mio_cyc_run(const uint8_t u8lc_init_val, const uint8_t u8lc_incr_val)
{
	diag_rcd_run_logic(u8lc_init_val, u8lc_incr_val);//程序顺序控制
	
	mio_creat_pulse_out(g_st_ram1.run_auxiliary_data.u16_do_val);//产生输出脉冲，内部取反运算
	
	/* Run Diagnostic */
	mio_diag(g_st_ram1.run_display_data.instrument_hmi.u8_mcu_addr);//MCU I/O口诊断
}


  uint16_t  DO_shiji =0u;

static void mio_creat_pulse_out(uint16_t u16_do_dat)
{
	uint16_t	u16_pul_dat		= 0u;
	u16_pul_dat	= (uint16_t)(~g_st_ram1.run_auxiliary_data.u16_do_pul);  //u16_do_pul永远只会55555555或AAAAAAAA
	g_st_ram1.run_auxiliary_data.u16_do_pul	= u16_pul_dat;
	u16_pul_dat	= u16_pul_dat & u16_do_dat ;
	//u32_pul_dat	= u32_pul_dat & u32_do_dat & PUL_DRV_OUTPUT;
	//u32_pul_dat	= u32_pul_dat | (u32_do_dat & NORMAL_DRV_OUTPUT);
	DO_shiji =u16_pul_dat;
	do_set_dat(&DO_shiji);//DO-IO口输出
	
	/* backup global variable */
	g_st_ram2.run_auxiliary_data.u16_do_pul	= g_st_ram1.run_auxiliary_data.u16_do_pul;//更新
}

void mio_get_di(const uint8_t u8lc_init_val, const uint8_t u8lc_incr_val, uint16_t * u16p_di_dat)
{
	/*
	uint8_t u8lv_i = 0u;
	*/
	uint16_t	u16la_dat[2u] = {0u};
	uint16_t	u16_val = 0u;

	diag_rcd_run_logic(u8lc_init_val, u8lc_incr_val);//程序顺序控制
	
	di_get_dat(u16la_dat);
	u16_val	= (uint16_t)(~u16la_dat[0]) & 0x03FFu;
	g_st_ram1.run_auxiliary_data.u16_di_val	= u16_val;//当前DI采样值放入RAM1中
	
	*u16p_di_dat	= g_st_ram1.run_auxiliary_data.u16_di_val;
	
	/* backup global variable */
	g_st_ram2.run_auxiliary_data.u16_di_val	= g_st_ram1.run_auxiliary_data.u16_di_val;//RAM2备份
}

 static void mio_diag(uint8_t u8_mcu_addr)
{
	uint16_t	u16_step_req	= 0u;
	uint16_t	u16_step_sta	= 0u;
	/* uint16_t	u16_step_ack	= 0u; */
	
	uint16_t	u16_step_tmp	= 0u;
	
	static uint16_t	s_u16_step_di	= 0u;
	static uint16_t	s_u16_step_do	= 0u;
	
	if(u8_mcu_addr == ADDR_MCU_A)//读取同步步数 --1.获取诊断步数
	{
		u16_step_req = dre_get_diag_rx_step();//MCUA是接收到同步步数
	}
	else if(u8_mcu_addr == ADDR_MCU_B)
	{
		u16_step_req = dre_get_diag_tx_step();//MCUB是对外发送步数
	}
	else
	{
		u16_step_req = 0u;
	}
	
	dre_protocol_poll();//2.维护SPI交互过程
	
	u16_step_tmp = (uint16_t)(u16_step_req >> 6u); //64个step，进行一步DI诊断
	if(s_u16_step_di != u16_step_tmp)
	{
		s_u16_step_di = u16_step_tmp;  //变了，更新值（0或1）
		mio_diag_di(s_u16_step_di, u16_step_sta, u8_mcu_addr);//DI诊断
	}
	else
	{
		;
	}
	
	dre_protocol_poll();   //4
	
	u16_sm_step = g_st_ram1.run_auxiliary_data.TimeStepNum ;
	
	u16_step_tmp = (uint16_t)(u16_step_req >> 6u);//64个step，进行一步DO诊断---5.获得新的诊断步数
	if(s_u16_step_do != u16_step_tmp)//步数发生变化才做DO诊断
	{
		s_u16_step_do = u16_step_tmp;	
		if(s_u16_step_do < DO_DIAG_STEP_MAX)//DO诊断的最大次数为6次，才能完整诊断完DO-6个MOS管,诊断一次DO故障在15s
		{			
			mio_diag_do(s_u16_step_do, u16_step_sta, u8_mcu_addr);
			g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		= 0u;
			g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	= comm_tim_get_currt_cnt();
		}
		else
		{

		}
		
			//u16_sm_step = g_st_ram1.run_auxiliary_data.TimeStepNum ;

//			if(u8_mcu_addr == ADDR_MCU_A)
//		{
//		  u16_sm_step =u16_sm_step +1u;
//			
//			g_st_ram1.run_auxiliary_data.TimeStepNum = u16_sm_step;
//		  g_st_ram2.run_auxiliary_data.TimeStepNum = u16_sm_step;
//		}	
		
		if((u8_mcu_addr == ADDR_MCU_A)&&((u16_sm_step&0x01u) == 0u))
		{
		  u16_sm_step =u16_sm_step +1u;
		}
		else if ((u8_mcu_addr == ADDR_MCU_B) &&((u16_sm_step&0x01u) == 1u))
		{
		 u16_sm_step =u16_sm_step +1u;
		}
		
		  g_st_ram1.run_auxiliary_data.TimeStepNum = u16_sm_step;
		  g_st_ram2.run_auxiliary_data.TimeStepNum = u16_sm_step;

	}
	else
	{
		mio_do_wire();//这是线路过流诊断，实际数据没有使用，可以去掉，但其他部分要一起修改   
	}
	
	dre_protocol_poll();  //维护SPI交互过程
	
	// if(u8_mcu_addr == ADDR_MCU_A)
	// {
		// dre_set_diag_tx_step(u16_step_req);
	// }
	// else if(u8_mcu_addr == ADDR_MCU_B)
	// {
		// dre_set_diag_ack_step(u16_step_req);
	// }
	// else
	// {
		// ;	/* abnormal */
	// }
	
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		= g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt;
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	= g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old;
}

/*************************************************************************************************
# Function : mio_diag_di
# Descriptions :
#	DI channel circuit diagnostic
# Input :
#	u16_step	: Diagnostic step
# Output :
#	None
# Return :
#	diag_step_ack / diag_step_tx
# Others :
#	u16_step -> 0		: N/A
#	         -> 1		: DI T1
#	         -> 2		: N/A
#	         -> 3		: DI T2
# History :
#	1. Author : decorn		Version : V1.0		Date : 2017-08-10
#		Modification: Create
#	2. 
#---------------------------------------------------------*/
static void mio_diag_di(uint16_t u16_step, uint16_t u16_sta, uint8_t u8_mcu_addr)
{
	uint16_t	u16_idx			= 0u;
	bool_t		b8_src_exist	= BFALSE;
	uint16_t	u16la_dat[1u]	= {0u};
	uint16_t	u16_val_normal	= 0u;
	uint16_t	u16_val			= 0u;
		if((u16_step == 0u)||(u16_step == 2u)||(u16_step == 4u) ||(u16_step == 6u)||(u16_step == 8u)||(u16_step == 10u))//若为偶数
	{
		/* DI T1 Diagnostic, Output pulse */
		if(u8_mcu_addr == ADDR_MCU_A) //若为偶数T1发低电平脉冲
		{
			di_get_dat(u16la_dat);//读取DI当前状态，用来判断故障恢复。
			/*
			在输出低电平脉冲之前，检查Di状态，重要
			*/
			u16_val_normal	= ((uint16_t)~u16la_dat[0]) & 0x03FFu;   //zhou 0x003Fu
			DI_DIAG_CLR_PULSE();//低电平置位
			soft_dly_us((g_st_ram1.config_parameter.factory_config_pra.u8_pulse_detection_gap)*1000u);//软件延时,1~5ms,默认2ms
			/* Get DI channel status */
			di_get_dat(u16la_dat);//延时后，马上读DI当前状态
			u16_val	= ((uint16_t)~u16la_dat[0]) & 0x03FFu;   //zhou 0x003Fu
			b8_src_exist = BTRUE;//mcu输出低电平脉冲这件事完成
		}
		else
		{
			;
		}
		DI_DIAG_SET_PULSE();//恢复为高电平
		/* u16_step_ack = u16_step; */
	}
		else if((u16_step == 1u)||(u16_step == 3u)||(u16_step == 5u)||(u16_step == 7u)||(u16_step == 9u)||(u16_step == 11u))//若为奇数
	{
		/* DI T2 Diagnostic, Output pulse */
		if(u8_mcu_addr == ADDR_MCU_B)//T2发高电平
		{
			di_get_dat(u16la_dat);//在输出低电平脉冲之前，检查DI状态，重要
			u16_val_normal	= ((uint16_t)~u16la_dat[0]) & 0x03FFu;   //zhou 0x003Fu
			DI_DIAG_CLR_PULSE();
			soft_dly_us((g_st_ram1.config_parameter.factory_config_pra.u8_pulse_detection_gap)*1000u);//软件延时,1~5ms,默认2ms
			/* Get DI channel status */
			di_get_dat(u16la_dat);
			u16_val	= ((uint16_t)~u16la_dat[0]) & 0x03FFu;//通道数据放在DI中 zhou 0x003Fu
			b8_src_exist = BTRUE;//MCU输出低电平脉冲这项工作完成
		}else
		{
			;
		}
		DI_DIAG_SET_PULSE();
		/* u16_step_ack = u16_step; */
	}
	else
	{
		DI_DIAG_SET_PULSE();//保持高电平
	}
	
	if(b8_src_exist == BTRUE)
	{
		for(u16_idx = 0u; u16_idx < MAX_IO_NUM_DI; u16_idx ++)
		{
			/* Handle fault , Only ON status check，只有在输入通道为ON的，做相关判定 */
			if((u16_val_normal & U16_SET_BIT[u16_idx]) != 0u)
			{
				if((u16_val & U16_SET_BIT[u16_idx]) != 0u)//在输出脉冲后，读取通道应该为低电平
				{
					//读到高电平，进入故障处理
					if(g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_cnt_sc < FAULT_DI_FILT_SC)
					{
						g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_cnt_sc += 2u;
						//滤波处理，连续判断故障3次（0,2,4）都为错，则认为错误
					}
					else
					{
						g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm |= BF_FAULT_DI_SC; 
						//g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta|= (uint16_t)U16_SET_BIT[u16_idx];
						//置上错误位
					}
				}
				else
				{
					/* Fault recover */
					if(0u < g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_cnt_sc)
					{
						//之前检测到故障，本次没有检测到，则进行故障恢复，每次递减
						g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_cnt_sc --;
					}
					else
					{ 
						g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm &= (uint8_t)~BF_FAULT_DI_SC;
						//g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta &= (uint16_t)U16_CLR_BIT[u16_idx];
						//清除故障标志
					}
					/*
					g_st_ram1.st_mio.st_diag_di_info[u16_idx].u8_fault_cnt_sc = 0u;
					g_st_ram1.st_mio.st_diag_di_info[u16_idx].u8_fault_confirm &= (uint8_t)~BF_FAULT_DI_SC;
					*/
				}
			}
			else
			{
				; /* Stay in the last status */
			}
			
			/* backup global variable */
			g_st_ram2.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_cnt_sc = \
			g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_cnt_sc;//短路故障检测次数计数
			g_st_ram2.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm = \
			g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm;//故障标志
			g_st_ram2.run_display_data.instrument_hmi.u32_st_dev_sta = \
			g_st_ram1.run_display_data.instrument_hmi.u32_st_dev_sta ;             //输入采样标志
		} 
	}else{
		;
	}
}

/*************************************************************************************************
# Function : mio_diag_do
# Descriptions :
#	DI channel circuit diagnostic
# Input :
#	u16_step	: Diagnostic step
# Output :
#	None
# Return :
#	diag_step_ack / diag_step_tx
# Others :
#	u16_step -> 0		: N/A
#	         -> 1		: DI T1
#	         -> 2		: N/A
#	         -> 3		: DI T2
# History :
#	1. Author : decorn		Version : V1.0		Date : 2017-08-10
#		Modification: Create
#	2. 
#---------------------------------------------------------*/
static void mio_diag_do(uint16_t u16_step, uint16_t u16_sta, uint8_t u8_mcu_addr)
{
	uint32_t	u32_do_test_patten		= 0u;
	uint32_t	u32_do_test_patten_res		= 0u;
	uint32_t  u32_time_cnt =0u;
	/* uint32_t	u32_do_test_pul_width	= 0u; */
	uint16_t	u16a_adc_raw_dat[10u]	= {0u};
	uint16_t	u16_adc_raw_dat1		= 0u;
	uint16_t	u16_adc_raw_dat2		= 0u;
	bool_t		b8_fault1				= BFALSE;
	bool_t		b8_fault2				= BFALSE;
	u32_do_test_patten	= g_st_ram1.run_auxiliary_data.u16_do_val;//读取当前DO输出
	u32_do_test_patten_res	= g_st_ram1.run_auxiliary_data.u16_do_val;//读取当前DO输出
	
	static  bool_t check_temp = 0u;
	        //从SPI交互取一个值
	        //判断改值奇偶
	        //奇数置1，执行MCU_A
	
	switch(u16_step)
	{
	case 0u :
	  {
		break;
	  }
	case 1u :
	  {
		/* Set MA-DO4=ON, MB-DO5(44)=OFF, MB-DO6(64)=ON ,测量U5是否短路*/
		if((u8_mcu_addr == ADDR_MCU_B) &&(u16_sm_step&0x01u == 0x00u))
		{
			do_diag_sw_set(ADC_DO_ASW_V44);//切换为测量44 线电压  3
			soft_dly_us(5u);//延时
			adc_get_raw_dat(u16a_adc_raw_dat);//获取ADC的值
			u32_do_test_patten &= ~BF_DO_T_DO5;//MB-DO5置0，关闭44下晶体管输出
			b8_fault1 = mio_do_pattern_out(u32_do_test_patten);//得到输出诊断结果
			mio_do_pattern_fault(u16a_adc_raw_dat[2], b8_fault1, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_44],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_44]);
			hmi_set_do_fault(DIAG_DO_IDX_44, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_44].u8_fault_confirm);//置DO HMI故障标
			
		}
		else
		{
			;
		}
		break;
	  }
	case 2u :
	{
		/* Set MA-DO4=ON, MB-DO5(44)=ON, MB-DO6(64)=OFF */
		if((u8_mcu_addr == ADDR_MCU_B) &&(u16_sm_step&0x01u == 0x00u))
		{
			do_diag_sw_set(ADC_DO_ASW_V64);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u32_do_test_patten &= ~BF_DO_T_DO6;
			b8_fault1 = mio_do_pattern_out(u32_do_test_patten);
			mio_do_pattern_fault(u16a_adc_raw_dat[2], b8_fault1, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_64],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_64]);
			hmi_set_do_fault(DIAG_DO_IDX_64, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_64].u8_fault_confirm);
		}
		else
		{
			;
		}
		break;
	}
	case 3u :{
		/* Set MA-DO4=OFF, MB-DO5(44)=ON, MB-DO6(64)=ON */
		if((u8_mcu_addr == ADDR_MCU_A) &&(u16_sm_step&0x01u == 0x01u))
			{
			do_diag_sw_set(ADC_DO_ASW_V64);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u16_adc_raw_dat1 = u16a_adc_raw_dat[2];
			
			do_diag_sw_set(ADC_DO_ASW_V44);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u16_adc_raw_dat2 = u16a_adc_raw_dat[2];
			
			u32_do_test_patten &= ~BF_DO_T_DO4;
			b8_fault2 = mio_do_pattern_out(u32_do_test_patten);
			do_diag_sw_set(ADC_DO_ASW_V64);
			soft_dly_us(5u);
			
			b8_fault1 = mio_do_pattern_out(u32_do_test_patten);
			mio_do_pattern_fault(u16_adc_raw_dat1, b8_fault1, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_64],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_64]);
			mio_do_pattern_fault(u16_adc_raw_dat2, b8_fault2, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_44],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_44]);
			hmi_set_do_fault(DIAG_DO_IDX_64, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_64].u8_fault_confirm);
			hmi_set_do_fault(DIAG_DO_IDX_44, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_44].u8_fault_confirm);
			
		}else{
			;
		}
		break;
	}
	case 4u :
	{
		/* Set MB-DO4=ON, MA-DO5(54)=OFF, MA-DO6(34)=ON */
		if((u8_mcu_addr == ADDR_MCU_A) &&(u16_sm_step&0x01u == 0x01u))
		{
			do_diag_sw_set(ADC_DO_ASW_V54);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u32_do_test_patten &= ~BF_DO_T_DO5;
			b8_fault1 = mio_do_pattern_out(u32_do_test_patten);
			mio_do_pattern_fault(u16a_adc_raw_dat[2], b8_fault1, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_54],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_54]);
			hmi_set_do_fault(DIAG_DO_IDX_54, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_54].u8_fault_confirm);
		}else
		{
			;
		}
		break;
	}
	case 5u :
	{
		/* Set MB-DO4=ON, MA-DO5(54)=ON, MA-DO6(34)=OFF */
		//if(u8_mcu_addr == ADDR_MCU_A)
		if((u8_mcu_addr == ADDR_MCU_A) &&(u16_sm_step&0x01u == 0x01u))
			{
			do_diag_sw_set(ADC_DO_ASW_V34);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u32_do_test_patten &= ~BF_DO_T_DO6;   
			b8_fault1 = mio_do_pattern_out(u32_do_test_patten);
			
			mio_do_pattern_fault(u16a_adc_raw_dat[2], b8_fault1, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_34],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_34]);
			hmi_set_do_fault(DIAG_DO_IDX_34, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_34].u8_fault_confirm);
		}else
		{
			;
		}
		break;
	}
	case 6u :
	{
		break;
	}
	case 7u :
	{
		/* Set MB-DO4=OFF, MA-DO5(54)=ON, MA-DO6(34)=ON */
		if((u8_mcu_addr == ADDR_MCU_B) &&(u16_sm_step&0x01u == 0x00u))
			{
			do_diag_sw_set(ADC_DO_ASW_V34);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u16_adc_raw_dat1 = u16a_adc_raw_dat[2];
			
			do_diag_sw_set(ADC_DO_ASW_V54);
			soft_dly_us(5u);
			adc_get_raw_dat(u16a_adc_raw_dat);
			u16_adc_raw_dat2 = u16a_adc_raw_dat[2];

				
			u32_do_test_patten &= ~BF_DO_T_DO4;     //当前DO输出
			b8_fault2 = mio_do_pattern_out(u32_do_test_patten);  //MOS管动作
			do_diag_sw_set(ADC_DO_ASW_V34);
			soft_dly_us(5u);
			
			b8_fault1 = mio_do_pattern_out(u32_do_test_patten);   //MOS管动作
	    
			do_diag_sw_set(ADC_DO_ASW_V34);
			soft_dly_us(5u);
			
			mio_do_pattern_fault(u16_adc_raw_dat1, b8_fault1, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_34],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_34]);
			
			mio_do_pattern_fault(u16a_adc_raw_dat[2], b8_fault2, \
							&g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_54],\
							&g_st_ram2.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_54]);
			hmi_set_do_fault(DIAG_DO_IDX_34, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_34].u8_fault_confirm);
			hmi_set_do_fault(DIAG_DO_IDX_54, \
						(uint16_t)g_st_ram1.run_auxiliary_data.st_diag_do_info[DIAG_DO_IDX_54].u8_fault_confirm);
		}else
		{
			;
		}
		break;
	}
	default : break;
	}
		//快速恢复 ，消除DO诊断过久
	do{
		soft_dly_us(10u);
		mio_creat_pulse_out((uint16_t) u32_do_test_patten_res);//恢复正常输出
		u32_time_cnt ++;
	}while(u32_time_cnt < 50);
}

static bool_t mio_do_pattern_out(uint32_t u32_pattern)
{
	uint32_t	u32_time_cnt			= 0u;
	bool_t		b8_fault				= BTRUE;
	uint16_t	u16a_adc_raw_dat[10u]	= {0u};
	
	b8_fault		= BTRUE;
	u32_time_cnt	= 0u;
	do{
		soft_dly_us(50u);
		mio_creat_pulse_out((uint16_t) u32_pattern);//除了要测试的MOS管外，其他MOS管按正常输出
		adc_get_raw_dat(u16a_adc_raw_dat);//发出脉冲之后，读ADC直到读的值小于预期值，或超时
		if(ADC_DO_PUL_LOW_V < u16a_adc_raw_dat[2])
		{
			/* Debug
			g_st_ram1.st_mio.st_diag_do_info[3].u16_current = u32_pattern;
			g_st_ram1.st_mio.st_diag_do_info[2].u16_current = u16a_adc_raw_dat[2];
			*/
			b8_fault = BTRUE;//有故障
		}
		else
		{
			b8_fault = BFALSE;//无故障
		}
		u32_time_cnt ++;
	}while((u32_time_cnt < ADC_DO_PUL_TIM_MAX) && (b8_fault == BTRUE));
	
	return b8_fault;
}

static void mio_do_pattern_fault(uint16_t u16_normal_val, bool_t b8_fault, \
							diag_do_info_t *stp_diag_info,\
							diag_do_info_t *stp_diag_info_bak)
							//u16_normal_val：当前输出值
							//b8_fault:诊断结果
							//stp_diag_info：诊断信息
							//stp_diag_info_bak：RAM2诊断信息的备份
{
	if(b8_fault == BTRUE)// 若ADC采样到DO故障，则进行故障累计处理
	{
		if(stp_diag_info->u8_fault_cnt_tp < FAULT_DO_FILT_TP)
		{
			stp_diag_info->u8_fault_cnt_tp ++;//
		}
		else
		{
			stp_diag_info->u8_fault_confirm |= BF_FAULT_DO_TP;//连续诊断到？次,置故障位，18次对应45s,6次对应15s
			
		}
	}
	else
	{
		if(ADC_DO_LIMIT_HIGH < u16_normal_val)//若当前输出为高电平，且测试正常
		{
			if(FAULT_DO_RECO_TP < stp_diag_info->u8_fault_cnt_tp)//之前有故障
			{
				stp_diag_info->u8_fault_cnt_tp -= FAULT_DO_RECO_TP;//则进行故障恢复处理
			}
			else
			{
				stp_diag_info->u8_fault_cnt_tp = 0u;//故障计数保持为0
				stp_diag_info->u8_fault_confirm &= ~BF_FAULT_DO_TP;
			}
		}
		else
		{
			;
		}
	}
	stp_diag_info_bak->u8_fault_cnt_tp	= stp_diag_info->u8_fault_cnt_tp;
	stp_diag_info_bak->u8_fault_confirm	= stp_diag_info->u8_fault_confirm;
}

static void mio_do_wire(void)
{
	uint32_t	u32_tmp_dat	= 0u;
	uint16_t	u16a_adc_raw_dat[10u]	= {0u};// ADC 采样值初始化

	if(g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt < ADC_DO_STABLE_TIM)
		{
		u32_tmp_dat	= comm_tim_calc_diff(&g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old);
		g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt += (uint16_t)u32_tmp_dat;
	  }
		else
		{
		g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		= 0u;
		g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	= comm_tim_get_currt_cnt();
		
		/* Get ADC sample value */
		adc_get_raw_dat(u16a_adc_raw_dat);
		switch(g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw)
			{
			case ADC_DO_ASW_C12 :{break;}
			case ADC_DO_ASW_C1 :
				{
				//g_st_ram1.run_auxiliary_data.st_diag_do_info[0].u16_current = u16a_adc_raw_dat[2];
				//g_st_ram2.run_auxiliary_data.st_diag_do_info[0].u16_current = u16a_adc_raw_dat[2];
				break;
			  }
			case ADC_DO_ASW_C2 :
				{
				//g_st_ram1.run_auxiliary_data.st_diag_do_info[1].u16_current = u16a_adc_raw_dat[2];
				//g_st_ram2.run_auxiliary_data.st_diag_do_info[1].u16_current = u16a_adc_raw_dat[2];
				break;
		   	}
			case ADC_DO_ASW_V44 :{
				g_st_ram1.run_auxiliary_data.st_diag_do_info[1].u16_voltage = u16a_adc_raw_dat[2];
				g_st_ram2.run_auxiliary_data.st_diag_do_info[1].u16_voltage = u16a_adc_raw_dat[2];
				break;
			}
			case ADC_DO_ASW_V64 :{
				g_st_ram1.run_auxiliary_data.st_diag_do_info[3].u16_voltage = u16a_adc_raw_dat[2];
				g_st_ram2.run_auxiliary_data.st_diag_do_info[3].u16_voltage = u16a_adc_raw_dat[2];
				break;
			}
			case ADC_DO_ASW_V54 :{
				g_st_ram1.run_auxiliary_data.st_diag_do_info[2].u16_voltage = u16a_adc_raw_dat[2];
				g_st_ram2.run_auxiliary_data.st_diag_do_info[2].u16_voltage = u16a_adc_raw_dat[2];
				break;
			}
			case ADC_DO_ASW_V34 :{
				g_st_ram1.run_auxiliary_data.st_diag_do_info[0].u16_voltage = u16a_adc_raw_dat[2];
				g_st_ram2.run_auxiliary_data.st_diag_do_info[0].u16_voltage = u16a_adc_raw_dat[2];
				break;
			}
			default : break;
		}
		if(g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw < ADC_DO_ASW_MAX)
		{
			g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw ++;
		}
		else
		{
			g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw = 0u;
		}
		g_st_ram2.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw = g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw;
	}
	
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		= g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_cnt		;
	g_st_ram2.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	= g_st_ram1.run_auxiliary_data.st_do_diag_sta.st_stable_tim.u16_tim_old	;	
	do_diag_sw_set(g_st_ram1.run_auxiliary_data.st_do_diag_sta.u8_do_diag_sw);//DO-ADC模拟开关选择
	
	
}

uint8_t mio_get_di_fault(void)
{
	uint8_t		u8_rtn	= 0u;
	uint16_t	u16_idx	= 0u;
	for(u16_idx = 0u; u16_idx < MAX_IO_NUM_DI; u16_idx ++){
		u8_rtn |= g_st_ram1.run_auxiliary_data.st_diag_di_info[u16_idx].u8_fault_confirm;
	}
	return u8_rtn;
}

void mio_set_do(const uint8_t u8lc_init_val, const uint8_t u8lc_incr_val, \
				uint16_t u16_do_dat, uint8_t u8_mcu_addr)
{
	diag_rcd_run_logic(u8lc_init_val, u8lc_incr_val);
	
	g_st_ram1.run_auxiliary_data.u16_do_val	= u16_do_dat & BF_DO_VAL_RO; //先配置继电器MA-DO1/DO2
	if(u8_mcu_addr == ADDR_MCU_A)
		{
		if((u16_do_dat & BF_DO_VAL_DO34) == BF_DO_VAL_DO34)  //BF_DO_VAL_DO34	0x0004u
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	|= BF_DO_T_DO6;
		  }
		else
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	&= ~BF_DO_T_DO6;   //BF_DO_T_DO6		0x0020u
		  }
		if(((u16_do_dat & BF_DO_VAL_DO44) == BF_DO_VAL_DO44)||((u16_do_dat & BF_DO_VAL_DO64) == BF_DO_VAL_DO64))
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	|= BF_DO_T_DO4;
		  }
		else
		  {
			g_st_ram1.run_auxiliary_data.u16_do_val	&= ~BF_DO_T_DO4;
		  }
		if((u16_do_dat & BF_DO_VAL_DO54) == BF_DO_VAL_DO54)
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	|= BF_DO_T_DO5;
		  }
		else
		  {
			g_st_ram1.run_auxiliary_data.u16_do_val	&= ~BF_DO_T_DO5;
		  }
	  }
 else
	{
		if(((u16_do_dat & BF_DO_VAL_DO54) == BF_DO_VAL_DO54)||((u16_do_dat & BF_DO_VAL_DO34) == BF_DO_VAL_DO34))
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	|= BF_DO_T_DO4;
		  }
		else
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	&= ~BF_DO_T_DO4;
		  }
		if((u16_do_dat & BF_DO_VAL_DO44) == BF_DO_VAL_DO44)
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	|= BF_DO_T_DO5;
		  }
		else
		  {
			g_st_ram1.run_auxiliary_data.u16_do_val	&= ~BF_DO_T_DO5;
		  }
		if((u16_do_dat & BF_DO_VAL_DO64) == BF_DO_VAL_DO64)
			{
			g_st_ram1.run_auxiliary_data.u16_do_val	|= BF_DO_T_DO6;
		  }
		else
		  {
			g_st_ram1.run_auxiliary_data.u16_do_val	&= ~BF_DO_T_DO6;
		  }
	}
	g_st_ram2.run_auxiliary_data.u16_do_val	= g_st_ram1.run_auxiliary_data.u16_do_val;
}

